// src/api/fileApi.js
// 前端文件上传和读取工具类

const fileApi = {
  /**
   * 上传文件到本地uploads目录
   * @param {string} category - 文件分类 (contract, acceptance, employee, etc.)
   * @param {File} file - 要上传的文件对象
   * @param {string} subPath - 子路径（可选）
   * @returns {Promise} 包含文件相对路径的Promise
   */
  uploadFile: async (category, file, subPath = '') => {
    try {
      // 构建文件路径
      const fileName = `${Date.now()}_${file.name}`;
      const relativePath = subPath ? `uploads/${category}/${subPath}/${fileName}` : `uploads/${category}/${fileName}`;
      
      // 检查文件大小限制（5MB）
      const maxSize = 5 * 1024 * 1024; // 5MB
      if (file.size > maxSize) {
        throw new Error(`文件大小超过限制，最大允许5MB，当前文件大小：${(file.size / 1024 / 1024).toFixed(2)}MB`);
      }
      
      // 使用IndexedDB存储文件，避免localStorage配额限制
      const fileData = {
        name: fileName,
        size: file.size,
        type: file.type,
        lastModified: file.lastModified,
        category,
        subPath: subPath || '',
        relativePath
      };
      
      // 将文件保存到IndexedDB
      await fileApi.saveFileToIndexedDB(fileData, file);
      
      return {
        success: true,
        data: {
          fileName,
          filePath: relativePath,
          size: file.size,
          type: file.type
        }
      };
    } catch (error) {
      console.error('文件上传失败:', error);
      
      // 提供更友好的错误信息
      let errorMessage = error.message;
      if (error.name === 'TransactionInactiveError') {
        errorMessage = '文件上传超时，请重试';
      } else if (error.message.includes('文件大小超过限制')) {
        errorMessage = error.message; // 保持原始错误信息
      } else if (error.message.includes('保存文件到IndexedDB失败')) {
        errorMessage = '文件保存失败，请检查浏览器存储空间';
      } else if (!error.message) {
        errorMessage = '文件上传失败，请重试';
      }
      
      return {
        success: false,
        error: errorMessage
      };
    }
  },

  /**
   * 下载文件
   * @param {string} category - 文件分类
   * @param {string} subPath - 子路径
   * @param {string} fileName - 文件名
   * @returns {Promise} 包含文件二进制数据的Promise
   */
  downloadFile: async (category, subPath, fileName) => {
    try {
      const fileRecord = await fileApi.getFileFromIndexedDB(category, subPath, fileName);
      
      // 将ArrayBuffer转换回Blob
      const blob = new Blob([fileRecord.data], { type: fileRecord.type });
      
      return {
        success: true,
        data: blob
      };
    } catch (error) {
      console.error('文件下载失败:', error);
      return {
        success: false,
        error: error.message
      };
    }
  },

  /**
   * 获取文件列表
   * @param {string} category - 文件分类
   * @param {string} subPath - 子路径
   * @returns {Promise} 包含文件列表的Promise
   */
  listFiles: async (category, subPath) => {
    try {
      const db = await fileApi.initIndexedDB();
      const transaction = db.transaction(['files'], 'readonly');
      const store = transaction.objectStore('files');
      const index = store.index('category');
      
      return new Promise((resolve, reject) => {
        const request = index.getAll(category);
        request.onsuccess = () => {
          const allFiles = request.result;
          const filteredFiles = allFiles
            .filter(file => file.subPath === subPath)
            .map(file => ({
              name: file.name,
              size: file.size,
              type: file.type,
              lastModified: file.lastModified,
              uploadTime: file.uploadTime
            }));
          
          resolve({
            success: true,
            data: filteredFiles
          });
        };
        request.onerror = () => reject(request.error);
      });
    } catch (error) {
      console.error('获取文件列表失败:', error);
      return {
        success: false,
        error: error.message
      };
    }
  },

  /**
   * 删除文件
   * @param {string} category - 文件分类
   * @param {string} subPath - 子路径
   * @param {string} fileName - 文件名
   * @returns {Promise} 包含删除结果的Promise
   */
  deleteFile: async (category, subPath, fileName) => {
    try {
      const db = await fileApi.initIndexedDB();
      const transaction = db.transaction(['files'], 'readwrite');
      const store = transaction.objectStore('files');
      const index = store.index('fileName');
      
      return new Promise((resolve, reject) => {
        const request = index.get(fileName);
        request.onsuccess = () => {
          const result = request.result;
          if (result && result.category === category && result.subPath === subPath) {
            const deleteRequest = store.delete(result.id);
            deleteRequest.onsuccess = () => {
              resolve({
                success: true,
                message: '文件删除成功'
              });
            };
            deleteRequest.onerror = () => reject(deleteRequest.error);
          } else {
            reject(new Error('文件不存在'));
          }
        };
        request.onerror = () => reject(request.error);
      });
    } catch (error) {
      console.error('文件删除失败:', error);
      return {
        success: false,
        error: error.message
      };
    }
  },

  /**
   * 上传项目合同文件
   * @param {string} projectName - 项目名称
   * @param {File} file - 合同文件
   * @returns {Promise} 包含文件路径的Promise
   */
  uploadProjectContract: (projectName, file) => {
    return fileApi.uploadFile('contract', file, `项目合同/${projectName}`);
  },

  /**
   * 上传验收文件
   * @param {string} projectName - 项目名称
   * @param {File} file - 验收文件
   * @returns {Promise} 包含文件路径的Promise
   */
  uploadAcceptanceFile: (projectName, file) => {
    return fileApi.uploadFile('acceptance', file, projectName);
  },

  /**
   * 上传员工档案文件
   * @param {string} employeeName - 员工姓名
   * @param {string} fileType - 文件类型 (入职登记表, 身份证, 学历证明等)
   * @param {File} file - 文件
   * @returns {Promise} 包含文件路径的Promise
   */
  uploadEmployeeFile: (employeeName, fileType, file) => {
    return fileApi.uploadFile('employee', file, `${fileType}/${employeeName}`);
  },

  /**
   * 上传员工证件照
   * @param {string} employeeName - 员工姓名
   * @param {File} file - 证件照文件
   * @returns {Promise} 包含文件路径的Promise
   */
  uploadEmployeePhoto: (employeeName, file) => {
    return fileApi.uploadEmployeeFile(employeeName, '证件照', file);
  },

  /**
   * 上传身份证复印件
   * @param {string} employeeName - 员工姓名
   * @param {File} file - 身份证文件
   * @returns {Promise} 包含文件路径的Promise
   */
  uploadIdCardCopy: (employeeName, file) => {
    return fileApi.uploadEmployeeFile(employeeName, '身份证', file);
  },

  /**
   * 上传学历证明
   * @param {string} employeeName - 员工姓名
   * @param {File} file - 学历证明文件
   * @returns {Promise} 包含文件路径的Promise
   */
  uploadDiploma: (employeeName, file) => {
    return fileApi.uploadEmployeeFile(employeeName, '学历证明', file);
  },

  /**
   * 上传入职登记表
   * @param {string} employeeName - 员工姓名
   * @param {File} file - 入职登记表文件
   * @returns {Promise} 包含文件路径的Promise
   */
  uploadHireForm: (employeeName, file) => {
    return fileApi.uploadEmployeeFile(employeeName, '入职登记表', file);
  },

  /**
   * 获取文件预览URL
   * @param {string} category - 文件分类
   * @param {string} subPath - 子路径
   * @param {string} fileName - 文件名
   * @returns {Promise<string>} 文件预览URL
   */
  getPreviewUrl: async (category, subPath, fileName) => {
    // 对于图片文件，创建blob URL
    try {
      const fileRecord = await fileApi.getFileFromIndexedDB(category, subPath, fileName);
      
      if (fileRecord && fileRecord.type.startsWith('image/')) {
        const blob = new Blob([fileRecord.data], { type: fileRecord.type });
        return URL.createObjectURL(blob);
      }
      
      return null;
    } catch (error) {
      console.error('获取预览URL失败:', error);
      return null;
    }
  },

  /**
   * 下载文件到本地
   * @param {string} category - 文件分类
   * @param {string} subPath - 子路径
   * @param {string} fileName - 文件名
   */
  downloadFileToLocal: async (category, subPath, fileName) => {
    try {
      const result = await fileApi.downloadFile(category, subPath, fileName);
      
      if (result.success) {
        const url = URL.createObjectURL(result.data);
        const link = document.createElement('a');
        link.href = url;
        link.download = fileName;
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
        URL.revokeObjectURL(url);
      } else {
        throw new Error(result.error);
      }
    } catch (error) {
      console.error('下载文件失败:', error);
      throw error;
    }
  },

  /**
   * 初始化IndexedDB
   * @returns {Promise<IDBDatabase>} IndexedDB数据库实例
   */
  initIndexedDB: () => {
    return new Promise((resolve, reject) => {
      const request = indexedDB.open('FileStorage', 1);
      
      request.onerror = () => reject(request.error);
      request.onsuccess = () => resolve(request.result);
      
      request.onupgradeneeded = (event) => {
        const db = event.target.result;
        if (!db.objectStoreNames.contains('files')) {
          const store = db.createObjectStore('files', { keyPath: 'id', autoIncrement: true });
          store.createIndex('category', 'category', { unique: false });
          store.createIndex('subPath', 'subPath', { unique: false });
          store.createIndex('fileName', 'fileName', { unique: false });
        }
      };
    });
  },

  /**
   * 保存文件到IndexedDB
   * @param {Object} fileData - 文件元数据
   * @param {File} file - 文件对象
   * @returns {Promise} 保存结果
   */
  saveFileToIndexedDB: async (fileData, file) => {
    try {
      // 先将文件转换为ArrayBuffer
      const arrayBuffer = await new Promise((resolve, reject) => {
        const reader = new FileReader();
        reader.onload = () => resolve(reader.result);
        reader.onerror = reject;
        reader.readAsArrayBuffer(file);
      });
      
      // 准备文件记录
      const fileRecord = {
        ...fileData,
        data: arrayBuffer,
        uploadTime: new Date().toISOString()
      };
      
      // 在文件转换完成后，再创建事务
      const db = await fileApi.initIndexedDB();
      const transaction = db.transaction(['files'], 'readwrite');
      const store = transaction.objectStore('files');
      
      // 使用Promise包装事务操作，确保在事务失效前完成
      return new Promise((resolve, reject) => {
        const request = store.add(fileRecord);
        
        request.onsuccess = () => {
          resolve({ success: true });
        };
        
        request.onerror = () => {
          console.error('IndexedDB添加操作失败:', request.error);
          reject(request.error);
        };
        
        // 监听事务完成事件
        transaction.oncomplete = () => {
          console.log('IndexedDB事务完成');
        };
        
        transaction.onerror = () => {
          console.error('IndexedDB事务失败:', transaction.error);
          reject(transaction.error);
        };
        
        transaction.onabort = () => {
          console.error('IndexedDB事务被中止:', transaction.error);
          reject(new Error('事务被中止'));
        };
      });
    } catch (error) {
      console.error('保存文件到IndexedDB失败:', error);
      throw error;
    }
  },

  /**
   * 从IndexedDB获取文件
   * @param {string} category - 文件分类
   * @param {string} subPath - 子路径
   * @param {string} fileName - 文件名
   * @returns {Promise} 文件数据
   */
  getFileFromIndexedDB: async (category, subPath, fileName) => {
    try {
      const db = await fileApi.initIndexedDB();
      const transaction = db.transaction(['files'], 'readonly');
      const store = transaction.objectStore('files');
      const index = store.index('fileName');
      
      return new Promise((resolve, reject) => {
        const request = index.get(fileName);
        request.onsuccess = () => {
          const result = request.result;
          if (result && result.category === category && result.subPath === subPath) {
            resolve(result);
          } else {
            reject(new Error('文件不存在'));
          }
        };
        request.onerror = () => reject(request.error);
      });
    } catch (error) {
      console.error('从IndexedDB获取文件失败:', error);
      throw error;
    }
  },

  /**
   * 清理过期的文件（超过7天）
   * @returns {Promise} 清理结果
   */
  cleanupExpiredFiles: async () => {
    try {
      const db = await fileApi.initIndexedDB();
      const transaction = db.transaction(['files'], 'readwrite');
      const store = transaction.objectStore('files');
      
      const sevenDaysAgo = new Date();
      sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7);
      
      const request = store.openCursor();
      const filesToDelete = [];
      
      request.onsuccess = (event) => {
        const cursor = event.target.result;
        if (cursor) {
          const fileRecord = cursor.value;
          const uploadTime = new Date(fileRecord.uploadTime);
          if (uploadTime < sevenDaysAgo) {
            filesToDelete.push(cursor.primaryKey);
          }
          cursor.continue();
        } else {
          // 删除过期文件
          filesToDelete.forEach(id => {
            store.delete(id);
          });
        }
      };
      
      return { success: true, deletedCount: filesToDelete.length };
    } catch (error) {
      console.error('清理过期文件失败:', error);
      throw error;
    }
  }
};

export default fileApi;